package net.mgsx.product.t2m.modisco;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import net.mgsx.product.t2m.modisco.tools.ModiscoUtils;

import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
import org.eclipse.gmt.modisco.java.Model;
import org.eclipse.gmt.modisco.java.NamedElement;
import org.eclipse.gmt.modisco.java.emf.JavaPackage;
import org.junit.BeforeClass;

public class ModiscoTestCase {

	@BeforeClass
	public static void initClass(){
		ModiscoUtils.setLogger(new TestCaseLogger());
	}
	
	/**
	 * Load a java model
	 * @param filename file path relative to the project
	 * @return the model or null if ko
	 */
	final protected Model loadModel(String filename)
	{
		// Initialize the meta-model
		JavaPackage.eINSTANCE.eClass();
		
		// Register the XMI resource factory for the .javaxmi extension
		Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE;
		Map<String, Object> m = reg.getExtensionToFactoryMap();
		m.put("javaxmi", new XMIResourceFactoryImpl());
		
		// Obtain a new resource set
		ResourceSet resSet = new ResourceSetImpl();
		
		// Get the resource
		Resource resource = resSet.getResource(URI.createURI(filename), true);
		
		// Get the first model element and cast it to the right type.
		return (Model)resource.getContents().get(0);
	}
	
	@SuppressWarnings("unchecked")
	final protected <T extends NamedElement> T findElement(EObject parent, String name, Class<? extends T> type) throws MultipleElementsFoundException
	{
		List<T> lst = new ArrayList<T>();
		for(TreeIterator<EObject> ite =  parent.eAllContents() ; ite.hasNext() ; ){
			EObject element = ite.next();
			if(type.isInstance(element) && ((NamedElement)element).getName().equals(name)){
				lst.add((T)element);
			}
		}
		if(lst.size() == 1){
			return lst.get(0);
		}else if(lst.size() > 0){
			throw new MultipleElementsFoundException("multiple elements (" + lst.size() + ") found for " + type.getSimpleName() + " " + name);
		}
		return null;
	} 
	
}
